#ifndef _CJOSMPARSER_H
#define _CJOSMPARSER_H

#include <vector>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "COsmCommon.h"
#include "COsmMap.h"

using namespace std;
/**
 * CJosmParser
 * This class is used for parsing OSM map stored in JOSM forma.
 */
class CJosmParser
{
public:
    /**
     * Constructor.
     * Constructor of class CJosmParser.
     */
    CJosmParser(){};

    /**
     * Destructor
     */
    ~CJosmParser(){};
 
    /**
     * LoadMap
     * Parse given map in JOSM format and
     * store it as COsmMap object.
     *
     * @param filename OSM map file in JOSM format (XML)
     * @param map OSM Map Storage (Object)
     * @return true if success
     */
    bool LoadMap(const char *filename,COsmMap *map);

    /**
     * SaveMap
     * Save OSM map stored in COsmMap object to file in JOSM format.
     *
     * @param filename Name of file to sove map
     * @param map OSM Map Storage (Object)
     * @return true id success
     */
    bool SaveMap(const char *filename,COsmMap *map);
   
private:

    /**
     * parseOSMBounds
     * Parse JOSM bounds elements.
     *
     * @param cur Current XML node pointer
     * @param bounds OSM Bounds Storage
     * @return true if success
     */
    bool parseOSMBounds(xmlNodePtr cur,COsmBounds *bounds);

    /**
     * parseOSMNode
     * Parse OSM node basic element.
     *
     * @param cur Current XML node pointer
     * @param nodes OSM Nodes Storage
     * @return true if success
     */
    bool parseOSMNode(xmlNodePtr cur,vector<COsmNode > &nodes);

    /**
     * parseOSMWay
     * Parse OSM way basic element.
     *
     * @param cur Current XML node pointer.
     * @param map OSM Map Storage (for node references)
     * @param ways OSM Ways Storage
     * @return true if success
     */
    bool parseOSMWay(xmlNodePtr cur,COsmMap *map,vector<COsmWay > &ways);

    /**
     * parseOSMRelation
     * Parse OSM relation basic element.
     *
     * @param cur Current XML node pointer.
     * @param relations OSM Relations Storage
     * @return true if success
     */
    bool parseOSMRelation(xmlNodePtr cur, vector<COsmRelation > &realtions);

    /**
     * parseOSMTags
     * Parse OSM tag subelements (within all basic elements)
     *
     * @param cur Current XML node pointer.
     * @param tags Vector for saving parsed tags.
     * @return true if success
     */
    bool parseOSMTags(xmlNodePtr cur, std::vector<tag_type > &tags);

    /**
     * parseOSMNds
     * Parse OSM nd (reference to nodes) subelements (within way element)
     *
     * @param cur Current XML node pointer
     * @param nds Vector for saving parsed nds.
     * @return true if success
     */
    bool parseOSMNds(xmlNodePtr cur, std::vector<long int > &nds,COsmMap *map);

    /**
     * parseOSMMembers
     * Parse OSM member subelements (within relation element)
     *
     * @param cur Current XML node pointer
     * @param members Vector for saving parsed members
     * return true if success
     */
    bool parseOSMMembers(xmlNodePtr cur, std::vector<member_type > &members);

    /**
     * findNeighbours
     * Find neighbours for all nodes.
     * @param nodes OSM Nodes Storage
     * @param ways OSM Ways Storage
     */
    void findNeighbours(vector<COsmNode > &nodes, vector<COsmWay > &ways);

    inline void toXmlChar(double d, xmlChar* c)
    {
        sprintf((char*)c,"%0.8f",d);
    }
    inline void toXmlChar(int i, xmlChar* c)
    {
        sprintf((char*)c,"%d",i);
    }
    inline void toXmlChar(long int i, xmlChar* c)
    {
        sprintf((char*)c,"%ld",i);
    }
};
#endif
